<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>

  <script>
    // 封装一个请求参数
    /* 
    如果有三个请求，第一个请求结束后，第二个请求要拿第一个请求的结果作为参数进行请求，
    第三个请求要拿第二个请求的结果作为参数进行请求
    如果层层嵌套的话，就会造成回调地狱，为了解决回调地狱，就采用了promise的链式调用的方式，
    一个请求结束后，return一个promise(也就是这个request(res+'')),后边的then就是这个promise成功的回调
    */
    function requestData(url) {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve(url)
        }, 2000)
      })
    }

    // // 链式调用的方式
    // requestData('lll').then(res1 => {
    //   return requestData(res1 + 'kobe')  //相当于第一个promise它resolve(requestData(res1+'kobe'))
    // }).then(res2 => {
    //   return requestData(res2 + 'dehua')
    // }).then(res3 => {
    //   console.log(res3);
    // })

    // // 使用生成器函数的方式
    // function* getData() {
    //   // 这个res1是第二个next传入的参数，yield后边的东西会进入到第一个next的返回对象中
    //   const res1 = yield requestData('lll') // 这个requestData会进入到第一个 {done:false,value:requestData('lll'}
    //   console.log("res1:", res1);
    //   const res2 = yield requestData(res1 + 'kobe')
    //   console.log("res2:", res2);
    //   const res3 = yield requestData(res2 + 'dehua')
    //   console.log("res3:", res3)
    //   console.log(res3);
    // }

    // let generator = getData()
    // generator.next().value.then(res1 => {
    //   generator.next(res1).value.then(res2 => {
    //     generator.next(res2).value.then(res3 => {
    //       generator.next(res3)
    //     })
    //   })
    // })

    // 生成器函数替换为async/await
    // async function getData() {
    //   // 这个res1是第二个next传入的参数，yield后边的东西会进入到第一个next的返回对象中
    //   const res1 = await requestData('lll') // 这个requestData会进入到第一个 {done:false,value:requestData('lll'}
    //   console.log("res1:", res1);
    //   const res2 = await requestData(res1 + 'kobe')
    //   console.log("res2:", res2);
    //   const res3 = await requestData(res2 + 'dehua')
    //   console.log("res3:", res3)
    //   console.log(res3);
    // }

    // getData()


    // 使用生成器函数的方式优化
    function* getData() {
      // 这个res1是第二个next传入的参数，yield后边的东西会进入到第一个next的返回对象中
      const res1 = yield requestData('lll') // 这个requestData会进入到第一个 {done:false,value:requestData('lll'}
      console.log("res1:", res1);
      const res2 = yield requestData(res1 + 'kobe')
      console.log("res2:", res2);
      const res3 = yield requestData(res2 + 'dehua')
      console.log("res3:", res3)
      const res4 = yield requestData(res3 + 'dehua')
      console.log("res4:", res4)
    }

    // let generator = getData()
    // generator.next().value.then(res1 => {
    //   generator.next(res1).value.then(res2 => {
    //     generator.next(res2).value.then(res3 => {
    //       generator.next(res3).value.then(res4 => {
    //         generator.next(res4)
    //       })
    //     })
    //   })
    // })

    // 自动化执行函数 
    // 递归
    function excGnFn(fn) {

      let genderator = fn()
      function exec(res) {
        let result = genderator.next(res)
        if (result.done) return
        result.value.then(res => {
          exec(res)
        })
      }

      exec()



    }

    excGnFn(getData)




  </script>

</body>

</html>